home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / msdos / fractal / fdesi313 / fdes308s / fdesmenu.c < prev    next >
Text File  |  1990-01-19  |  14KB  |  452 lines

  1. /*
  2.         Routines for menus using mouse
  3. */
  4. #include <stdio.h>
  5. #include <graphics.h>
  6. #include <stdlib.h>
  7. #include <stdarg.h>
  8. #include <string.h>
  9. #include <dir.h>
  10. #include <conio.h>
  11. #include <dos.h>
  12. #include "fdestria.h"
  13. #include "fdesequa.h"
  14. #include "fdesfile.h"
  15. #include "fdesmous.h"
  16. #include "fdesplot.h"
  17. #define CURSOR_RIGHT (77<<8)    /* cursor right key */
  18. #define CURSOR_LEFT (75<<8)    /* cursor left key */
  19.  
  20. float area_scaled;               /* area scale factor from zooming */
  21. typedef struct {
  22.     int selections;        /* number of selections */
  23.     char *item[16];        /* 16 strings that represent selections */
  24.     } popmenu;
  25.  
  26. #define ITEM_HEIGHT 20        /* Item height in pixels */
  27. #define CHAR_WIDTH 8        /* Item width per character in pixels */
  28.  
  29. /* ************************************************************************
  30.     pop-up menus
  31. ************************************************************************ */
  32. /* menu routines */
  33. int popup(int x, int y, popmenu *menu, int foreground, int background)
  34.                 /* display a pop-up menu and wait for mouse
  35.                    selection */
  36. {
  37. int i,rcode;
  38. int left,top,right,bottom;
  39. void *scr_save;
  40. mouse_state m;
  41. int maxwidth;
  42.     maxwidth = 0;
  43.     for (i=0; i<(*menu).selections; i++) {
  44.         if (strlen((*menu).item[i]) > maxwidth)
  45.             maxwidth = strlen((*menu).item[i]);
  46.     }
  47.     left = x;
  48.     top = y;
  49.     right = x + CHAR_WIDTH*maxwidth + 2;
  50.     bottom = y + (*menu).selections*ITEM_HEIGHT;
  51.     scr_save = malloc(imagesize(left,top,right,bottom));
  52.         if (scr_save == NULL)
  53.         {
  54.                 restorecrtmode();
  55.                 printf("Out of Memory, Sorry.");
  56.                 exit(0);
  57.         }
  58.     /* save screen portion */
  59.     getimage(left,top,right,bottom,scr_save);
  60.     /* display pop-up menu */
  61.         setfillstyle(SOLID_FILL,background);
  62.     bar(left,top,right,bottom);
  63.         setcolor(foreground);
  64.     for (i=0; i<(*menu).selections; i++) {
  65.         outtextxy(left+2,top+i*ITEM_HEIGHT+6,(*menu).item[i]);
  66.     }
  67.     /* input selection from mouse */
  68.     do {
  69.         mouse_click(&m);
  70.         rcode = (m.row - top - 2)/ITEM_HEIGHT + 1;
  71.     } while ((rcode < 1) || (rcode > (*menu).selections)
  72.         || !((m.col >= left) && (m.col <= right)));
  73.  
  74.     /* restore screen portion */
  75.     putimage(left,top,scr_save,COPY_PUT);
  76.     free(scr_save);
  77.     return(rcode);
  78. }
  79.  
  80. int mleft[10],mtop[10],mright,mbottom;
  81. void *mscr_save[10];
  82. int mscr_sp = -1;
  83. /*
  84.         putmsg
  85.         returns next pixel in X direction
  86. */
  87. int putmsg(int x, int y, char *str, int colorbk, int colorfo) /* display a pop-up message */
  88. {
  89.         if (strlen(str) == 0) return(x);
  90.         mscr_sp++;
  91.     mleft[mscr_sp] = x;
  92.         mtop[mscr_sp] = y;
  93.     mright = x + strlen(str)*CHAR_WIDTH + 2;
  94.     mbottom = y + ITEM_HEIGHT;
  95.         mscr_save[mscr_sp] = malloc(imagesize(mleft[mscr_sp],mtop[mscr_sp],
  96.                                               mright,mbottom));
  97.         if (mscr_save[mscr_sp] == NULL)
  98.         {
  99.                 restorecrtmode();
  100.                 printf("Out of Memory, Sorry.");
  101.                 exit(0);
  102.         }
  103.     /* save screen portion */
  104.         getimage(mleft[mscr_sp],mtop[mscr_sp],mright,mbottom,mscr_save[mscr_sp]);
  105.     /* display pop-up menu */
  106.     setfillstyle(SOLID_FILL,colorbk);
  107.         bar(mleft[mscr_sp],mtop[mscr_sp],mright,mbottom);
  108.     setcolor(colorfo);
  109.     outtextxy(mleft[mscr_sp]+2,mtop[mscr_sp]+6,str);
  110.         return(mright+1);
  111. }
  112. void clrmsg(void)
  113. {
  114.     /* restore screen portion */
  115.     if (mscr_sp < 0) {
  116.                 restorecrtmode();
  117.         printf("Too many pops of message text");
  118.         exit(0);
  119.     }
  120.         putimage(mleft[mscr_sp],mtop[mscr_sp],mscr_save[mscr_sp],COPY_PUT);
  121.     free(mscr_save[mscr_sp--]);
  122. }
  123. /*
  124.         putmsg destructive
  125. */
  126. int putmsg_d(int x, int y, char *str, int colorbk, int colorfo) /* display a pop-up message */
  127. {
  128. int mleft,mright,mtop,mbottom;
  129.         if (strlen(str) == 0) return(x);
  130.         mleft = x;
  131.         mtop = y;
  132.     mright = x + strlen(str)*CHAR_WIDTH + 2;
  133.     mbottom = y + ITEM_HEIGHT;
  134.     /* display pop-up menu */
  135.     setfillstyle(SOLID_FILL,colorbk);
  136.         bar(mleft,mtop,mright,mbottom);
  137.     setcolor(colorfo);
  138.         outtextxy(mleft+2,mtop+6,str);
  139.         return(mright+1);
  140. }
  141.  
  142. /* ************************************************************************
  143.         A 'scanf' for graphics mode
  144.         returns # of arguments
  145. ************************************************************************ */
  146. int gscanf(int x, int y, char *prompt, int maxlength, char *format, ...)
  147. {
  148. char buf[133];
  149. int si;                 /* string index into buf */
  150. va_list parmlist;
  151. unsigned int ch;
  152. int input_x;
  153. int i;
  154. int rcode;
  155. int mleft, mtop, mright, mbottom;
  156.  
  157.         input_x = putmsg(x,y,prompt,YELLOW,RED);
  158.  
  159.         for (i=0; i<maxlength; i++) buf[i]='_';
  160.         buf[maxlength] = 0;
  161.         putmsg(input_x, y, buf, WHITE, BLUE);
  162.  
  163.         buf[0] = 0;     /* null the string */
  164.         si = 0;
  165.         do {
  166.                 if ((ch = getch()) == 0) ch = getch() << 8;
  167.  
  168.                 if (ch == 015) break;          /* carriage return */
  169.                 if (ch == 033)                 /* escape */
  170.                 {
  171.                         clrmsg();
  172.                         clrmsg();
  173.                         return(0);
  174.                 }
  175.                 switch (ch)
  176.                 {
  177.             case 010:      /* backspace */
  178.                                 if (si == 0) break;
  179.                                 si--;
  180.                                 buf[si] = 0;
  181.                                 break;
  182.                         default:
  183.                                 if (si == maxlength) break;
  184.                                 buf[si++] = ch;
  185.                                 buf[si] = 0;
  186.                                 break;
  187.                 }
  188.         mleft = input_x;
  189.         mtop = y;
  190.         mright = input_x + maxlength*CHAR_WIDTH + 2;
  191.         mbottom = y + ITEM_HEIGHT;
  192.         setfillstyle(SOLID_FILL,WHITE);
  193.         bar(mleft,mtop,mright,mbottom);
  194.         setcolor(BLUE);
  195.         outtextxy(mleft+2,mtop+6,buf);
  196.         } while (1);
  197.  
  198.     if (strlen(buf) != 0)
  199.     {
  200.         va_start(parmlist,format);
  201.         rcode = vsscanf(buf,format,parmlist);
  202.         va_end(parmlist);
  203.     }
  204.         else rcode = 0;
  205.         clrmsg();
  206.         clrmsg();
  207.         return(rcode);
  208. }
  209.  
  210. /***************************************************************************
  211.         Returns filename pointed to by mouse
  212. ****************************************************************************/
  213. int fname_cmp(char *s1,char *s2)
  214. {
  215.     return(strcmp(s1,s2));
  216. }
  217. char trn_select[15];
  218. char *trn_directory(void)         /* returns NULL if no files */
  219. {
  220. struct ffblk ffblock;
  221. int num_files,i;
  222. mouse_state m;
  223. char trn_files[240][9];
  224. char fname[15];
  225.         cleardevice();
  226.         if (findfirst("*.TRN",&ffblock,0) == -1)
  227.         {
  228.                 putmsg(100,100,"No .TRN files in directory",BLUE,WHITE);
  229.                 mouse_click(&m);
  230.                 clrmsg();
  231.                 return(NULL);
  232.         }
  233.         else {
  234.                 num_files = 0;
  235.                 /* get directory from DOS */
  236.                 do {
  237.             strncpy(fname,ffblock.ff_name,14);
  238.             stpcpy(trn_files[num_files],strtok(fname,". "));
  239.             num_files++;
  240.         } while ((findnext(&ffblock) == 0) && (num_files < 240));
  241.         qsort(trn_files[0],num_files,9,fname_cmp);
  242.                 /* display on screen */
  243.                 cleardevice();
  244.         setcolor(LIGHTGREEN);
  245.                 for (i=0; i<num_files; i++)
  246.                 {
  247.             outtextxy((i/30)*80,(i%30)*10,trn_files[i]);
  248.                 }
  249.                 /* input mouse pointer */
  250.                 putmsg(0,330,"Click Left to view, Right to End",RED,WHITE);
  251.  
  252.                 plot_type = 1;                 /* do a small plot while inputting */
  253.                 mouse_idle_job = doIFSrand;     /* do a small plot while inputting */
  254.                 do {
  255.                         mouse_click(&m);
  256.             if (m.buttons & MOUSE_LEFT)
  257.                         {
  258.                                 i = (m.row/10)%30 + (m.col/80)*30;
  259.  
  260.                                 if (i>(num_files-1))
  261.                                 {
  262.                                         putmsg(100,100,"click on filename",WHITE,RED);
  263.                                         delay(1000);
  264.                                         clrmsg();
  265.                                 }
  266.                                 else
  267.                                 {
  268.                                         stpcpy(trn_select,trn_files[i]);
  269.  
  270.                                         /* load in the file */
  271.                                         if (trnfile_load(trn_select) != 0) {
  272.                                                 IFS_changed = 1;
  273.                                         }
  274.                                 }
  275.                         }
  276.                 } while (!(m.buttons & MOUSE_RIGHT));
  277.                 clrmsg();
  278.  
  279.                 mouse_idle_job = mouse_idle;
  280.         return(trn_select);
  281.         }
  282.         ;
  283. }
  284. /*****************************************************************************
  285.         Non-destructive line drawing
  286. ******************************************************************************/
  287. void *line_stack[10];
  288. int left[10],top[10];
  289.  
  290. int lsp = -1;
  291. void line_ovly(int x1,int y1,int x2,int y2)
  292. {
  293. int right,bottom;
  294.         lsp++;
  295.         if (x1 <= x2)
  296.         {
  297.                 left[lsp] = max(0,x1 - 2);
  298.                 right = min(x2 + 2,maxx);
  299.         }
  300.         else
  301.         {
  302.                 left[lsp] = max(0,x2 - 2);
  303.                 right = min(x1 + 2,maxx);
  304.         }
  305.         if (y1 <= y2)
  306.         {
  307.                 top[lsp] = max(0,y1 - 2);
  308.                 bottom = min(y2 + 2,maxy);
  309.         }
  310.         else
  311.         {
  312.                 top[lsp] = max(0,y2 - 2);
  313.                 bottom = min(y1 + 2,maxy);
  314.         }
  315.         line_stack[lsp] = malloc(imagesize(left[lsp],top[lsp],right,bottom));
  316.     getimage(left[lsp],top[lsp],right,bottom,line_stack[lsp]);
  317.         setcolor(WHITE);
  318.         line(x1,y1,x2,y2);
  319. }
  320. void line_clear(void)
  321. {
  322.     putimage(left[lsp],top[lsp],line_stack[lsp],COPY_PUT);
  323.         free(line_stack[lsp]);
  324.         lsp--;
  325. }
  326. /******************************************************************************
  327.         Mouse input of a zoom box
  328. ******************************************************************************/
  329. void box_new(int *x1, int *y1, int *x2, int *y2)
  330. {
  331. mouse_state m;
  332. float widthx,widthy;
  333. float centerx,centery;
  334. int oldcol,oldrow;
  335. float oldwidthx,oldwidthy;
  336. float oldcenterx,oldcentery;
  337.  
  338.     widthx = 300.0;
  339.         widthy = widthx*3.0/4.0;
  340.         centerx = maxx/2.0;
  341.     centery = maxy/2.0;
  342.         m.row = maxy/2.0;
  343.         m.col = maxx/2.0;
  344.     mouse_put(&m);
  345.     *x1 = centerx - widthx/2.0;
  346.         *x2 = centerx + widthx/2.0;
  347.         *y1 = centery - widthy/2.0;
  348.     *y2 = centery + widthy/2.0;
  349.     while (mouse_get(&m) != 0x00) ;
  350.         putmsg(10,10,"Press any key to accept",YELLOW,BLACK);
  351.     setlinestyle(DASHED_LINE,0,NORM_WIDTH);
  352.         line_ovly(*x1,*y1,*x1,*y2);
  353.         line_ovly(*x2,*y1,*x2,*y2);
  354.         line_ovly(*x1,*y1,*x2,*y1);
  355.         line_ovly(*x1,*y2,*x2,*y2);
  356.         oldrow = m.row;
  357.         oldcol = m.col;
  358.         do
  359.         {
  360.                 mouse_get(&m);
  361.                 oldwidthx = widthx;
  362.                 oldwidthy = widthy;
  363.                 oldcenterx = centerx;
  364.                 oldcentery = centery;
  365.                 if ((m.col != oldcol) || (m.row != oldrow))
  366.                 {
  367.             if (m.buttons&MOUSE_LEFT)
  368.                         {
  369.                 widthx *= (1.0 + (m.row-oldrow)/100.0);
  370.                 if (widthx < 20.0) widthx = 20.0;
  371.                                 widthy = widthx*3.0/4.0;
  372.                         }
  373.                         else
  374.                         {
  375.                 centerx += (m.col-oldcol);
  376.                 centery += (m.row-oldrow);
  377.                         }
  378.                         m.row = maxy/2.0;
  379.                         m.col = maxx/2.0;
  380.                         mouse_put(&m);
  381.                         *x1 = centerx - widthx/2.0;
  382.                         *x2 = centerx + widthx/2.0;
  383.                         *y1 = centery - widthy/2.0;
  384.             *y2 = centery + widthy/2.0;
  385.             if ((*x1 <= 2.0) || (*x2 >maxx-2.0) || (*y1 <= 2.0)
  386.                 || (*y2 >= (maxy-2.0)))
  387.                         {
  388.                                 widthx = oldwidthx;
  389.                                 widthy = oldwidthy;
  390.                                 centerx = oldcenterx;
  391.                                 centery = oldcentery;
  392.                                 *x1 = centerx - widthx/2.0;
  393.                                 *x2 = centerx + widthx/2.0;
  394.                                 *y1 = centery - widthy/2.0;
  395.                                 *y2 = centery + widthy/2.0;
  396.                         }
  397.                         line_clear();
  398.                         line_clear();
  399.                         line_clear();
  400.             line_clear();
  401.             line_ovly(*x1,*y1,*x1,*y2);
  402.                         line_ovly(*x2,*y1,*x2,*y2);
  403.                         line_ovly(*x1,*y1,*x2,*y1);
  404.                         line_ovly(*x1,*y2,*x2,*y2);
  405.                         oldcol = m.col;
  406.                         oldrow = m.row;
  407.                 }
  408.     } while (!kbhit());
  409.     if (getch() == 0) getch();
  410.         line_clear();
  411.         line_clear();
  412.         line_clear();
  413.         line_clear();
  414.         clrmsg();
  415. }
  416. /******************************************************************************
  417.         Zooming on plot
  418.         This code really belongs somewhere else.
  419. ******************************************************************************/
  420. void zoom_in(void)
  421. {
  422. int x1,y1,x2,y2;
  423. float xscale,xoffset,yscale,yoffset;
  424.  
  425.         putmsg(0,0,"Zoom Box",BLUE,WHITE);
  426.         box_new(&x1,&y1,&x2,&y2);
  427.         clrmsg();
  428.  
  429.         if (x1 == x2) return;
  430.         if (y1 == y2) return;
  431.         xscale = maxx/(x2-x1);
  432.         yscale = maxy/(y2-y1);
  433.         if (xscale > yscale) xscale = yscale;
  434.         else yscale = xscale;
  435.         xoffset = -((x1+x2)/2.0)*xscale + maxx/2.0;
  436.         yoffset = -((y1+y2)/2.0)*yscale + maxy/2.0;
  437.  
  438.         /* scale relative to already scaled triangles */
  439.         IFS_rescale(xscale,xoffset,yscale,yoffset,1);
  440.         area_scaled *= xscale;
  441.         area_scaled *= yscale;
  442. }
  443. void zoom_out(void)
  444. {
  445.         area_scaled = 1.0;
  446.         IFS_changed = 1;
  447.     cleardevice();
  448.     doIFSrand();
  449. }
  450.  
  451.  
  452.